#include "systemmonitor.h"
#include "../mongo/mongoagent.h"

#define  WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <iphlpapi.h>
#include <winsock2.h>

#include "../plc/plcconnecter.h"
#include "systemconfig.h"
#include "log/log.h"
#include "../servo/servoagent.h"
#include "soem/soemethercat.h"
#include "../rtc5/rtc5agent.h"
#include "../plc/plcdataprocess.h"

namespace HIM {

std::atomic_bool sysAlarm{true};

std::atomic_bool plcConnAlarm{true};
std::atomic_bool servoConnAlarm{true};
std::atomic_bool rtc5ConnAlarm{true};
std::atomic_bool dbConnAlarm{true};

uint16_t plcData[100]{0};
Drive_Inputs feedInputs{0,0,0,0,0,0,0,0,0};
Drive_Inputs manInputs{0,0,0,0,0,0,0,0,0};
Drive_Inputs powInputs{0,0,0,0,0,0,0,0,0};

std::atomic_bool feedIsEnble{false};
std::atomic_bool manIsEnble{false};
std::atomic_bool powIsEnble{false};

std::atomic_bool rtcErr{true};
std::atomic_bool HeaterTemperatureErr{true};
std::atomic_bool laserSafe{false};

std::atomic_int laserStatus{-1};

std::vector<std::pair<std::string,std::string>> NetworkInfosList;

void SystemMonitorThread::run()
{
    QTimer timer;
    connect(&timer,&QTimer::timeout,this,&SystemMonitorThread::on_timeout,Qt::DirectConnection);
    timer.start(250);
    exec();
    return;
}

void SystemMonitorThread::on_timeout()
{
    SYSTEMMONITOR.doDataSync();
}

SystemMonitor::SystemMonitor():
    systemMonitorThread(new SystemMonitorThread)
{
    qRegisterMetaType<QMap<int, float>>("QMap<int, float>");
}

SystemMonitor::~SystemMonitor()
{
    systemMonitorThread->quit();
    systemMonitorThread->wait();
    delete systemMonitorThread;

    networkCardDisonnect();
    plcDisconnect();
    rtcDisconnect();
    dbDisconnect();
}

bool SystemMonitor::getNetworkCordInfo(std::vector<std::pair<std::string,std::string>>& NetworkInfos)
{
    PIP_ADAPTER_INFO pAdapterInfo;
    PIP_ADAPTER_INFO pAdapter = NULL;
    DWORD dwRetVal = 0;
    ULONG ulOutBufLen = sizeof(IP_ADAPTER_INFO);
    bool getNetworkCordInfo{false};

    pAdapterInfo = (IP_ADAPTER_INFO*)malloc(sizeof(IP_ADAPTER_INFO));
    if (pAdapterInfo == NULL) {
        HIM_ERROR("Error allocating memory needed to call GetAdaptersInfo");
        return getNetworkCordInfo;
    }

    if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW){
        free(pAdapterInfo);
        pAdapterInfo = (IP_ADAPTER_INFO*)malloc(ulOutBufLen);
        if (pAdapterInfo == NULL) {
            HIM_ERROR("Error allocating memory needed to call GetAdaptersInfo");
            return getNetworkCordInfo;
        }
    }

    if ((dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) == NO_ERROR) {
        pAdapter = pAdapterInfo;
        while (pAdapter) {
            NetworkInfos.push_back(
                        std::make_pair<std::string,std::string>(pAdapter->Description,pAdapter->AdapterName));
            pAdapter = pAdapter->Next;
        }
        getNetworkCordInfo = true;
    } else {
        HIM_ERROR("Error allocating memory needed to call GetAdaptersInfo");
    }

    if (pAdapterInfo) {
        free(pAdapterInfo);
    }
    return  getNetworkCordInfo;
};

void SystemMonitor::on_initApp()
{ 
    plcConnect();
    networkCardConnect();
    rtcConnect();
    initSyncMap();

    systemMonitorThread->start();
}

void SystemMonitor::initSyncMap()
{
    QMap<int,float> syncMap;

    bool isAlarm{false};

    bool plcConnAlarmNew{false};
    bool servoConnAlarmNew{false};
    bool rtc5ConnAlarmNew{false};
    bool dbConnAlarmNew{false};

    if(PLCCONNECTER.getConnectStatus()){
        if(PLCCONNECTER.readRegisters(0,100,plcData)){
            plcConnAlarmNew = false;
            syncMap[label_statusairsupplyvalve] = PLCDATAPROCESSER.GetPlcFloatData(SO_VD4_0,plcData);
            syncMap[label_statusWashingvalvePressure] = PLCDATAPROCESSER.GetPlcFloatData(SO_VD8_0,plcData);
            syncMap[label_statusO2] = PLCDATAPROCESSER.GetPlcFloatData(SO_VD12_0,plcData);
            syncMap[label_statsusAirO2] = PLCDATAPROCESSER.GetPlcFloatData(SO_VD16_0,plcData);
            syncMap[label_statusEnvTemperature] = PLCDATAPROCESSER.GetPlcFloatData(SO_VD20_0,plcData);
            syncMap[label_statusBaseTemperature] = PLCDATAPROCESSER.GetPlcFloatData(SO_VD24_0,plcData);
            syncMap[label_cp_3] = PLCDATAPROCESSER.GetPlcFloatData(SO_VD28_0,plcData);
            syncMap[label_statusSpeedFan] = PLCDATAPROCESSER.GetPlcFloatData(SO_VD32_0,plcData);
            syncMap[label_cp_2] = PLCDATAPROCESSER.GetPlcFloatData(SO_VD36_0,plcData);
            syncMap[label_cp_7] = PLCDATAPROCESSER.GetPlcFloatData(SO_VD40_0,plcData);
            syncMap[label_cp_8] = PLCDATAPROCESSER.GetPlcFloatData(SO_VD44_0,plcData);
            syncMap[label_cp_9] = PLCDATAPROCESSER.GetPlcWordData(SO_VW48_0,plcData);
            syncMap[label_alarm_fan] = PLCDATAPROCESSER.GetPlcBitData(SO_V50_8,plcData);;
            if( syncMap[label_alarm_fan]>0)
                isAlarm = true;
            syncMap[label_loopCleanStatus] = PLCDATAPROCESSER.GetPlcBitData(SO_V52_15,plcData);
            syncMap[label_alarm_watercooling] = PLCDATAPROCESSER.GetPlcBitData(SO_V52_0,plcData);
            if(syncMap[label_alarm_watercooling]>0)
                isAlarm = true;

            syncMap[label_alarm_cabinDoor] = PLCDATAPROCESSER.GetPlcBitData(SO_V52_1,plcData);


            if(syncMap[label_alarm_cabinDoor]>0){
                laserSafe.store(false);
            }else{
                laserSafe.store(true);
            }

            if(syncMap[label_alarm_cabinDoor]>0)
                isAlarm = true;
            syncMap[label_alarm_O2] = PLCDATAPROCESSER.GetPlcBitData(SO_V52_2,plcData);
            if(syncMap[label_alarm_O2]>0)
                isAlarm = true;
            syncMap[label_alarm_cabinPressure] = PLCDATAPROCESSER.GetPlcBitData(SO_V52_3,plcData);
            if( syncMap[label_alarm_cabinPressure]>0)
                isAlarm = true;
            syncMap[label_statusCabinPressure] = PLCDATAPROCESSER.GetPlcFloatData(SO_VD68_0,plcData);
        }
        else{
            plcConnAlarmNew = true;
            isAlarm = true;
        }
    }
    else{
        plcConnAlarmNew = true;
        isAlarm = true;
    }

    if(get_driveInput(SERVOAGENT.servoParasMap[FEED].servoNO,feedInputs)){
        servoConnAlarmNew = false;
        syncMap[label_alarm_servoFeed] = feedInputs.ErrCode;
        if(feedInputs.ErrCode>0)
            isAlarm = true;
        feedIsEnble.store(feedInputs.StatusWord & (1<<2));
        syncMap[pushButton_servoFeedEnable] = feedIsEnble.load();

        feedInPlace.store(feedInputs.StatusWord & (1<<10));

        feedPos.store((double)feedInputs.PositionFeedback
                      /(double)SERVOAGENT.servoParasMap[FEED].servoStepsPerMM);

        syncMap[label_statusServoFeed] = feedPos.load();
    }else{
        servoConnAlarmNew = true;
        isAlarm = true;
    }

    if(get_driveInput(SERVOAGENT.servoParasMap[MANUFACTURE].servoNO,manInputs)){
        servoConnAlarmNew = false;
        syncMap[label_alarm_servoMan] = manInputs.ErrCode;
        if(manInputs.ErrCode>0)
            isAlarm = true;
        manIsEnble.store(manInputs.StatusWord & (1<<2));
        syncMap[pushButton_servoManufactureEnable] = manIsEnble.load();
        manInPlace.store(manInputs.StatusWord & (1<<10));
        manPos.store((double)manInputs.PositionFeedback/(double)SERVOAGENT.servoParasMap[MANUFACTURE].servoStepsPerMM);
        syncMap[label_statusServoMan] = manPos.load();
    }else{
        servoConnAlarmNew = true;
        isAlarm = true;
    }

    if(get_driveInput(SERVOAGENT.servoParasMap[POWDER].servoNO,powInputs)){
        servoConnAlarmNew = false;
        syncMap[label_alarm_servoPow] = powInputs.ErrCode;
        if(powInputs.ErrCode>0)
            isAlarm = true;
        powIsEnble.store(powInputs.StatusWord & (1<<2));
        syncMap[pushButton_servoPowderEnable] = powIsEnble.load();
        powInPlace.store(powInputs.StatusWord & (1<<10));
        powPos.store((double)powInputs.PositionFeedback/(double)SERVOAGENT.servoParasMap[POWDER].servoStepsPerMM);
        syncMap[label_statusServoPowder] =powPos.load() ;
    }else{
        servoConnAlarmNew = true;
        isAlarm = true;
    }

    //TODO 同步激光器状态
    if(RTC5AGENT.getRtcIsInit()){
        rtc5ConnAlarmNew = false;
        if(!RTC5AGENT.CheckError()){
            rtcErr.store(false);
            syncMap[label_alarm_laser] = false ;
        }else{
            isAlarm = true;
        }
    }else{
        rtc5ConnAlarmNew = true;
        isAlarm = true;
    }

    if(MONGOAGENT.getConnectStatus()){
        dbConnAlarmNew = false;
    }else{
        dbConnAlarmNew = true;
        isAlarm = true;
    }

    //TODO 基板温度报警
    syncMap[label_alarm_EnvTemp] = false ;
    HeaterTemperatureErr.store(false);

    if(sysAlarm.load() != isAlarm){
        syncMap[toolButton_deviceStatus] = isAlarm;
        sysAlarm.store(isAlarm);

        if(isAlarm)
            sysStatus = SYS_ERR;
        else
            sysStatus = SYS_NORMAL;
    }

    if(plcConnAlarm.load() != plcConnAlarmNew){
        syncMap[label_alarm_plcConn] = plcConnAlarmNew;
        plcConnAlarm.store(plcConnAlarmNew);
    }

    if(servoConnAlarm.load() != servoConnAlarmNew){
        syncMap[label_alarm_ethrrcatConn] = servoConnAlarmNew;
        servoConnAlarm.store(servoConnAlarmNew);
    }

    if(rtc5ConnAlarm.load() != rtc5ConnAlarmNew){
        syncMap[label_alarm_rtcConn] = rtc5ConnAlarmNew;
        rtc5ConnAlarm.store(rtc5ConnAlarmNew);
    }

    if(dbConnAlarm.load() != dbConnAlarmNew){
        syncMap[label_alarm_mongoDBConn] = dbConnAlarmNew;
        dbConnAlarm.store(dbConnAlarmNew);
    }

    if(syncMap.size()>0){
        emit dataSynchronous(syncMap);
    }
}

bool plcDataCmp(AddressIndex index, DataType dataType, float& data ,uint16_t PlcDataNew[100])
{
    switch (dataType) {
    case BIT:{
        data = PLCDATAPROCESSER.GetPlcBitData(index,PlcDataNew);
        if(data!=PLCDATAPROCESSER.GetPlcBitData(index,plcData)){
            return true;
        }else{
            return false;
        };
    }break;
    case INT_16:{
        data = PLCDATAPROCESSER.GetPlcWordData(index,PlcDataNew);
        if(data!=PLCDATAPROCESSER.GetPlcWordData(index,plcData)){
            return true;
        }else{
            return false;
        };
    }break;
    case FLOAT_32:{
        data = PLCDATAPROCESSER.GetPlcFloatData(index,PlcDataNew);
        if(data!=PLCDATAPROCESSER.GetPlcFloatData(index,plcData)){
            return true;
        }else{
            return false;
        };
    }break;
    default:{
        return false;
    }break;
    }
}

void SystemMonitor::doDataSync()
{
    // TODO 判断舱体门是否已经关闭
    PLCDATAPROCESSER.setPlcData();

    QMap<int,float> syncMap;
    bool isAlarm{false};

    bool plcConnAlarmNew{false};
    bool servoConnAlarmNew{false};
    bool rtc5ConnAlarmNew{false};
    bool dbConnAlarmNew{false};

    if(PLCCONNECTER.getConnectStatus()){
        uint16_t PlcDataNew[100];
        if(PLCCONNECTER.readRegisters(0,100,PlcDataNew)){
            plcConnAlarmNew = false;

            if(0!=memcmp(PlcDataNew,plcData,100*sizeof(uint16_t))){

                float data;
                if(plcDataCmp(SO_VD4_0,FLOAT_32,data,PlcDataNew)){
                    syncMap[label_statusairsupplyvalve] = data;
                }

                if(plcDataCmp(SO_VD8_0,FLOAT_32,data,PlcDataNew)){
                    syncMap[label_statusWashingvalvePressure] = data;
                }

                if(plcDataCmp(SO_VD12_0,FLOAT_32,data,PlcDataNew)){
                    syncMap[label_statusO2] = data;
                }

                if(plcDataCmp(SO_VD16_0,FLOAT_32,data,PlcDataNew)){
                    syncMap[label_statsusAirO2] = data;
                }

                if(plcDataCmp(SO_VD20_0,FLOAT_32,data,PlcDataNew)){
                    syncMap[label_statusEnvTemperature] = data;
                }

                if(plcDataCmp(SO_VD24_0,FLOAT_32,data,PlcDataNew)){
                    syncMap[label_statusBaseTemperature] = data;
                }

                if(plcDataCmp(SO_VD28_0,FLOAT_32,data,PlcDataNew)){
                    syncMap[label_cp_3] = data;
                }

                if(plcDataCmp(SO_VD32_0,FLOAT_32,data,PlcDataNew)){
                    syncMap[label_statusSpeedFan] = data;
                }

                if(plcDataCmp(SO_VD36_0,FLOAT_32,data,PlcDataNew)){
                    syncMap[label_cp_2] = data;
                }

                if(plcDataCmp(SO_VD40_0,FLOAT_32,data,PlcDataNew)){
                    syncMap[label_cp_7] = data;
                }

                if(plcDataCmp(SO_VD44_0,FLOAT_32,data,PlcDataNew)){
                    syncMap[label_cp_8] = data;
                }

                if(plcDataCmp(SO_VW48_0,INT_16,data,PlcDataNew)){
                    syncMap[label_cp_9] = data;
                }

                if(plcDataCmp(SO_V50_8,BIT,data,PlcDataNew)){
                    syncMap[label_alarm_fan] = data;
                    if(data>0){
                        isAlarm = true;
                    }
                }

                if(plcDataCmp(SO_V52_15,BIT,data,PlcDataNew)){
                    syncMap[label_loopCleanStatus] = data;
                }

                if(plcDataCmp(SO_V52_0,BIT,data,PlcDataNew)){
                    syncMap[label_alarm_watercooling] = data;
                    if(data>0){
                        isAlarm = true;
                    }
                }

                if(plcDataCmp(SO_V52_1,BIT,data,PlcDataNew)){
                    syncMap[label_alarm_cabinDoor] = data;
                    if(data>0){
                        isAlarm = true;
                    }
                }

                if(plcDataCmp(SO_V52_2,BIT,data,PlcDataNew)){
                    syncMap[label_alarm_O2] = data;
                    if(data>0){
                        isAlarm = true;
                    }
                }

                if(plcDataCmp(SO_V52_3,BIT,data,PlcDataNew)){
                    syncMap[label_alarm_cabinPressure] = data;
                    if(data>0){
                        isAlarm = true;
                    }
                }

                if(plcDataCmp(SO_V52_5,BIT,data,PlcDataNew)){
                    if(data>0){
                        laserSafe.store(true);
                    }else{
                        laserSafe.store(false);
                    }
                }

                if(plcDataCmp(SO_VD68_0,FLOAT_32,data,PlcDataNew)){
                    syncMap[label_statusCabinPressure] = data;
                }
                memcpy(plcData,PlcDataNew,100*sizeof(uint16_t));
            }
        }else{
            plcConnAlarmNew = true;
            isAlarm = true;
        }
    }else{
        plcConnAlarmNew = true;
        isAlarm = true;
    }

    Drive_Inputs feedInputsNew;
    if(get_driveInput(SERVOAGENT.servoParasMap[FEED].servoNO,feedInputsNew)){
        servoConnAlarmNew = false;
        if(0!=memcmp(&feedInputsNew,&feedInputs,sizeof(feedInputsNew))){
            if(feedInputsNew.ErrCode != feedInputs.ErrCode){
                syncMap[label_alarm_servoFeed] = feedInputsNew.ErrCode;
                if(feedInputsNew.ErrCode>0){
                    isAlarm = true;
                }
            }

            if(feedInputsNew.StatusWord != feedInputs.StatusWord){

                feedIsEnble.store(feedInputsNew.StatusWord & (1<<2));
                bool oldStatat = feedInputs.StatusWord & (1<<2);

                if(feedIsEnble.load()!=oldStatat){
                    syncMap[pushButton_servoFeedEnable] = feedIsEnble.load();
                }
            }

            //        if(feedInputsNew.ModeOpDisplay != feedInputs.ModeOpDisplay){
            //            servoSyncMap[3]=feedInputsNew.ModeOpDisplay;
            //        }

            if(feedInputsNew.PositionFeedback != feedInputs.PositionFeedback){
                feedInPlace.store(feedInputs.StatusWord & (1<<10));
                feedPos.store((double)feedInputs.PositionFeedback
                              /(double)SERVOAGENT.servoParasMap[FEED].servoStepsPerMM);
                syncMap[label_statusServoFeed] = feedPos.load();
            }

            //        if(feedInputsNew.SpeedFeedback != feedInputs.SpeedFeedback){
            //            servoSyncMap[5]=feedInputsNew.SpeedFeedback;
            //        }
            //        if(feedInputsNew.TorqueFeedback != feedInputs.TorqueFeedback){
            //            servoSyncMap[6]=feedInputsNew.TorqueFeedback;
            //        }
            //        if(feedInputsNew.ProbeStatus != feedInputs.ProbeStatus){
            //            servoSyncMap[7]=feedInputsNew.ProbeStatus;
            //        }
            //        if(feedInputsNew.Probe1RisingPosFeedback != feedInputs.Probe1RisingPosFeedback){
            //            servoSyncMap[8]=feedInputsNew.Probe1RisingPosFeedback;
            //        }
            //        if(feedInputsNew.DIInputStatus != feedInputs.DIInputStatus){
            //            servoSyncMap[9]=feedInputsNew.DIInputStatus;
            //        }
            feedInputs = feedInputsNew;
        }
    }else{
        servoConnAlarmNew = true;
        isAlarm = true;
    }

    Drive_Inputs manInputsNew;
    if(get_driveInput(SERVOAGENT.servoParasMap[MANUFACTURE].servoNO,manInputsNew)){
        servoConnAlarmNew = false;
        if(0!=memcmp(&manInputsNew,&manInputs,sizeof(manInputsNew))){
            if(manInputsNew.ErrCode != manInputs.ErrCode){
                syncMap[label_alarm_servoMan]=manInputsNew.ErrCode;
                if(manInputsNew.ErrCode>0){
                    isAlarm = true;
                }
            }
            if(manInputsNew.StatusWord != manInputs.StatusWord){
                manIsEnble.store(manInputsNew.StatusWord & (1<<2));
                bool oldStatat = manInputs.StatusWord & (1<<2);

                if(manIsEnble.load()!=oldStatat){
                    syncMap[pushButton_servoManufactureEnable] = manIsEnble.load();
                }
            }
            //        if(manInputsNew.ModeOpDisplay != manInputs.ModeOpDisplay){
            //            servoSyncMap[13]=manInputsNew.ModeOpDisplay;
            //        }
            if(manInputsNew.PositionFeedback != manInputs.PositionFeedback){
                manInPlace.store(manInputs.StatusWord & (1<<10));
                manPos.store((double)manInputs.PositionFeedback/(double)SERVOAGENT.servoParasMap[MANUFACTURE].servoStepsPerMM);
                syncMap[label_statusServoMan] = manPos.load();
            }
            //        if(manInputsNew.SpeedFeedback != manInputs.SpeedFeedback){
            //            servoSyncMap[15]=manInputsNew.SpeedFeedback;
            //        }
            //        if(manInputsNew.TorqueFeedback != manInputs.TorqueFeedback){
            //            servoSyncMap[16]=manInputsNew.TorqueFeedback;
            //        }
            //        if(manInputsNew.ProbeStatus != manInputs.ProbeStatus){
            //            servoSyncMap[17]=manInputsNew.ProbeStatus;
            //        }
            //        if(manInputsNew.Probe1RisingPosFeedback != manInputs.Probe1RisingPosFeedback){
            //            servoSyncMap[18]=manInputsNew.Probe1RisingPosFeedback;
            //        }
            //        if(manInputsNew.DIInputStatus != manInputs.DIInputStatus){
            //            servoSyncMap[19]=manInputsNew.DIInputStatus;
            //        }
            manInputs = manInputsNew;
        }
    }else{
        servoConnAlarmNew = true;
        isAlarm = true;
    }

    Drive_Inputs powInputsNew;
    if(get_driveInput(SERVOAGENT.servoParasMap[POWDER].servoNO,powInputsNew)){
        servoConnAlarmNew = false;
        if(0!=memcmp(&powInputsNew,&powInputs,sizeof(powInputsNew))){
            if(powInputsNew.ErrCode != powInputs.ErrCode){
                syncMap[label_alarm_servoPow]=powInputsNew.ErrCode;
                if(powInputsNew.ErrCode>0){
                    isAlarm = true;
                }
            }
            if(powInputsNew.StatusWord != powInputs.StatusWord){
                powIsEnble.store(powInputsNew.StatusWord & (1<<2));
                bool oldStatat = powInputs.StatusWord & (1<<2);

                if(powIsEnble.load()!=oldStatat){
                    syncMap[pushButton_servoPowderEnable] = powIsEnble.load();
                }
            }
            //        if(powInputsNew.ModeOpDisplay != powInputs.ModeOpDisplay){
            //            servoSyncMap[23]=powInputsNew.ModeOpDisplay;
            //        }
            if(powInputsNew.PositionFeedback != powInputs.PositionFeedback){
                powInPlace.store(powInputs.StatusWord & (1<<10));
                powPos.store((double)powInputs.PositionFeedback/(double)SERVOAGENT.servoParasMap[POWDER].servoStepsPerMM);
                syncMap[label_statusServoPowder] =powPos.load();
            }
            //        if(powInputsNew.SpeedFeedback != powInputs.SpeedFeedback){
            //            servoSyncMap[25]=powInputsNew.SpeedFeedback;
            //        }
            //        if(powInputsNew.TorqueFeedback != powInputs.TorqueFeedback){
            //            servoSyncMap[26]=powInputsNew.TorqueFeedback;
            //        }
            //        if(powInputsNew.ProbeStatus != powInputs.ProbeStatus){
            //            servoSyncMap[27]=powInputsNew.ProbeStatus;
            //        }
            //        if(powInputsNew.Probe1RisingPosFeedback != powInputs.Probe1RisingPosFeedback){
            //            servoSyncMap[28]=powInputsNew.Probe1RisingPosFeedback;
            //        }
            //        if(powInputsNew.DIInputStatus != powInputs.DIInputStatus){
            //            servoSyncMap[29]=powInputsNew.DIInputStatus;
            //        }

            powInputs = powInputsNew;
        }
    }else{
        servoConnAlarmNew = true;
        isAlarm = true;
    }

    //TODO 同步激光器状态
    if(RTC5AGENT.getRtcIsInit()){
        rtc5ConnAlarmNew = false;
        bool rtcErrNew = RTC5AGENT.CheckError();
        if(rtcErrNew != rtcErr.load()){
            syncMap[label_alarm_laser] = rtcErrNew;
            rtcErr.store(rtcErrNew);

            if(rtcErrNew)
                isAlarm = true;
        }
    }else{
        rtc5ConnAlarmNew = true;
        isAlarm = true;
    }

    if(MONGOAGENT.getConnectStatus()){
        dbConnAlarmNew = false;
    }else{
        dbConnAlarmNew = true;
        isAlarm = true;
    }

    if(sysAlarm.load() != isAlarm){
        syncMap[toolButton_deviceStatus] = isAlarm;
        sysAlarm.store(isAlarm);

        if(isAlarm){
            sysStatus = SYS_ERR;
        }else{
            sysStatus = SYS_NORMAL;
        }
    }

    if(plcConnAlarm.load() != plcConnAlarmNew){
        syncMap[label_alarm_plcConn] = plcConnAlarmNew;
        plcConnAlarm.store(plcConnAlarmNew);
    }

    if(servoConnAlarm.load() != servoConnAlarmNew){
        syncMap[label_alarm_ethrrcatConn] = servoConnAlarmNew;
        servoConnAlarm.store(servoConnAlarmNew);
    }

    if(rtc5ConnAlarm.load() != rtc5ConnAlarmNew){
        syncMap[label_alarm_rtcConn] = rtc5ConnAlarmNew;
        rtc5ConnAlarm.store(rtc5ConnAlarmNew);
    }

    if(dbConnAlarm.load() != dbConnAlarmNew){
        syncMap[label_alarm_mongoDBConn] = dbConnAlarmNew;
        dbConnAlarm.store(dbConnAlarmNew);
    }

    if(syncMap.size()>0){
        emit dataSynchronous(syncMap);
    }
}

void SystemMonitor::connectAll()
{    
    if(plcConnAlarm.load()){
        plcConnect();
    }
    if(servoConnAlarm.load()){
        networkCardConnect();
    }
    if(rtc5ConnAlarm.load()){
        rtcConnect();
    }
}

bool SystemMonitor::networkCardConnect()
{
    try{
        string ifname = SYSTEMCONFIG.getValue(PARAMETER,"servoAdrName");
        return  SERVOAGENT.initSoemEthercat(ifname);
    }catch(std::exception& e){
        string errStr = "Ethercat init err:";
        HIM_ERROR(errStr.append(e.what()));
        return false;
    }
}

void SystemMonitor::plcConnect()
{
    try{
        std::string ip = SYSTEMCONFIG.getValue(PARAMETER,"lineEdit_PLC_IP");
        uint16_t port = SYSTEMCONFIG.getLongValue(PARAMETER,"lineEdit_PLC_Port");
        PLCCONNECTER.startConnect(ip,port,1);
    }catch(std::exception& e){
        string errStr = "PLC Connect err:";
        HIM_ERROR(errStr.append(e.what()));
    }
}

void SystemMonitor::rtcConnect()
{
    try{
        RTC5AGENT.init();
    }catch(std::exception& e){
        string errStr = "RTC5 Connect err:";
        HIM_ERROR(errStr.append(e.what()));
    }
}

void SystemMonitor::dbConnect()
{

}

void SystemMonitor::networkCardDisonnect()
{
    try{
        SERVOAGENT.disInitSoemEthercat();
    }catch(std::exception& e){
        string errStr = "Ethercat stop err:";
        HIM_ERROR(errStr.append(e.what()));
    }
}

void SystemMonitor::plcDisconnect()
{
    try{
        PLCCONNECTER.stopConnect();
    }catch(std::exception& e){
        string errStr = "plc disconnect err:";
        HIM_ERROR(errStr.append(e.what()));
    }
}

void SystemMonitor::rtcDisconnect()
{
    try{
        RTC5AGENT.Free();
    }catch(std::exception& e){
        string errStr = "RTC5 free err:";
        HIM_ERROR(errStr.append(e.what()));
    }
}

void SystemMonitor::dbDisconnect()
{

}

void SystemMonitor::loadAllConfig()
{
    applySysParas();
    applyServoParas();
    applyLaserParas();
}

void SystemMonitor::applySysParas()
{

}

void SystemMonitor::applyServoParas()
{
    SERVOAGENT.loadAllServoConfig();
}

void SystemMonitor::applyLaserParas()
{
    RTC5AGENT.loadAllLaserConfig();
}

bool SystemMonitor::laserSafeCheck()
{
    return laserSafe.load();
}

bool SystemMonitor::getServosEnable()
{
    return feedIsEnble.load()&manIsEnble.load()&powIsEnble.load();
}

//TODO
//灰桶24小时清理提醒

//刮刀运行检查两个杠高度

//

}
